package de.homelabs.moonrat.context.plugin.template;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import de.homelabs.moonrat.config.MoonratConfigurationManager;
import de.homelabs.moonrat.exception.MoonratErrorCode;
import de.homelabs.moonrat.exception.MoonratException;
import de.homelabs.moonrat.template.MoonratTemplate;
import de.homelabs.moonrat.util.MoonratWebUtils;

@Service
public class TemplateFilesystemDataProvider implements ITemplateDataProvider {

	static Logger logger = Logger.getLogger(TemplateFilesystemDataProvider.class);
	static final String VERSION = "0.1";
	static final String PROVIDERKEY = "template_data_provider";
	static final String DATAPROVIDERNAME = "templateFilesystemDataProvider";
	
	
	Map<String, MoonratTemplate> templateList = new HashMap<String, MoonratTemplate>();
	
	private @Autowired
	HttpServletRequest request;
	
	@Autowired
	private MoonratConfigurationManager mRCfgManager;
	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.IDataProvider#getVersion()
	 */
	public String getVersion() { return VERSION; }

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.IDataProvider#getProviderKey()
	 */
	public String getProviderKey() { return PROVIDERKEY; }

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.plugin.template.ITemplateDataProvider#getTemplate(java.lang.String)
	 */
	public MoonratTemplate getTemplate(String templateName) throws MoonratException{
		// check if template has previously been loaded
		if (templateList.containsKey(templateName)){
			//get and return template
			return templateList.get(templateName);
		} else {
			//load an registered template
			String domain = MoonratWebUtils.getDomainFromRequest(request);
			logger.debug(domain + " : " +templateName);
			String templatePath = mRCfgManager.getConfig().getRootPath() + "/" + domain + "/template/";
			//see if template exists
			File file = new File(templatePath + templateName);
			if (file.exists()){
				MoonratTemplate template = new MoonratTemplate();
				template.setName(templateName);
				template.setModificationDate(file.lastModified());
				template.setTemplatePath(templatePath);
				//add to template list
				templateList.put(templateName, template);
				return template;
			} else {
				return null;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.plugin.template.ITemplateDataProvider#getTemplateReader(de.homelabs.moonrat.template.MoonratTemplate)
	 */
	public Reader getTemplateReader(MoonratTemplate template) throws MoonratException {
		if (template.getReader() != null){
			return template.getReader();
		} else {
			File file = new File(template.getTemplatePath() + template.getName());
			try {
				InputStreamReader reader = new InputStreamReader(new FileInputStream(file));
				template.setReader(reader);
				template.setFile(file);
				return reader;
			} catch (FileNotFoundException e) {
				throw new MoonratException(MoonratErrorCode.TEMPLATE_NOT_FOUND, e);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.plugin.template.ITemplateDataProvider#getTemplateLastModified(de.homelabs.moonrat.template.MoonratTemplate)
	 */
	public long getTemplateLastModified(MoonratTemplate template) throws MoonratException {
		if (template != null && template.getFile() != null)
			return template.getFile().lastModified();
		else {
			throw new MoonratException(MoonratErrorCode.TEMPLATE_NOT_FOUND);
		}
	}

	@Override
	public boolean closeTemplateReader(MoonratTemplate template)
			throws MoonratException {
		MoonratTemplate mRTemplate = (MoonratTemplate) template;
		if (mRTemplate.getReader() != null){
			try {
				mRTemplate.getReader().close();
			} catch (IOException e) {
				//TODO: create MoonratErrorCode
				return false;
			}
			return true;
		} else {
			return false;
		}
	}

	@Override
	public String getProviderName() {
		return DATAPROVIDERNAME;
	}

}
